import 'package:flutter/material.dart';
import 'package:ui_widgets/src/refresh/refresh_container.dart';

import 'footer_widget.dart';

/// Copyright (C), 2021-2023, Franky Lee
/// @ProjectName: vmcard
/// @Package:
/// @ClassName: load_state
/// @Description:
/// @Author: frankylee
/// @CreateDate: 2023/5/23 11:45
/// @UpdateUser: frankylee
/// @UpdateData: 2023/5/23 11:45
/// @UpdateRemark: 更新说明

class MessageCustomListView<T> extends StatefulWidget {
  const MessageCustomListView({
    super.key,
    this.onLoadMore,
    this.data,
    this.historyData,
    this.renderItem,
    this.footerState = LoadState.idle,
    this.sliverHeader,
    this.header,
    this.footer,
    this.empty,
    this.physics,
    this.controller,
    this.padding,
    this.reverse = false,
    this.isAllowScroll = true,
  });

  /// 加载更多历史消息
  final Future<void> Function()? onLoadMore;

  /// 新消息列表
  final List<T>? data;

  /// 历史消息列表
  final List<T>? historyData;

  /// render item
  /// 回调列表的item到外部
  final Widget Function(
    BuildContext context,
    int index,
    dynamic item,
  )? renderItem;

  /// 顶部加载状态
  final LoadState? footerState;

  /// 列表顶部和底部组件
  final Widget? header;
  final Widget? footer;

  /// sliver header
  final List<Widget>? sliverHeader;

  /// 列表为空时组件
  final Widget? empty;

  /// 外部scroll physics
  /// /// 一般使用内部处理的就好
  final ScrollPhysics? physics;

  /// 外部scroll controller
  /// 一般使用内部处理的就好，除非有特殊的情况要处理
  final ScrollController? controller;

  /// 列表内容padding
  final EdgeInsets? padding;

  /// 消息列表反转
  final bool reverse;

  /// 时候运行消息滑动
  final bool isAllowScroll;

  @override
  MessageCustomListViewState createState() => MessageCustomListViewState();
}

class MessageCustomListViewState extends State<MessageCustomListView> {
  late ScrollController _scrollController;

  GlobalKey footerKey = GlobalKey();

  bool _loadMore = false;

  void _load() async {
    if (widget.footerState == LoadState.noMore ||
        widget.footerState == LoadState.loading ||
        widget.footerState == null) {
      return;
    }
    _loadMore = true;
    await widget.onLoadMore?.call();
    _loadMore = false;
  }

  @override
  void initState() {
    _scrollController = widget.controller ?? ScrollController();
    _scrollController.addListener(
      () {
        if (_scrollController.position.extentAfter < 500 && !_loadMore) {
          _load();
        }
      },
    );
    super.initState();
  }

  @override
  void didUpdateWidget(MessageCustomListView oldWidget) {
    super.didUpdateWidget(oldWidget);

    // 如果新消息数量增加了，自动滚动到底部
    if (widget.data != null) {
      if (widget.data!.length != oldWidget.data?.length) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (!_scrollController.hasClients) return;
          _scrollController.animateTo(
            0.0,
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeOut,
          );
        });
      }
    }
  }

  /// custom scrollview
  Widget _buildScrollView() {
    int dataLength = widget.data?.length ?? 0;
    int hisDataLength = widget.historyData?.length ?? 0;
    bool shrinkWrap = (dataLength + hisDataLength) < 20;
    Widget child = SliverToBoxAdapter(
      child: Container(),
    );
    Widget historyChild = SliverToBoxAdapter(
      child: Container(),
    );
    Widget footer = Container();

    // 历史消息显示
    if (widget.historyData != null && widget.historyData!.isNotEmpty) {
      historyChild = SliverList(
        delegate: SliverChildBuilderDelegate(
          childCount: widget.historyData?.length ?? 0,
          (context, index) {
            return widget.renderItem
                ?.call(context, index, widget.historyData?[index]);
          },
        ),
      );

      footer = FooterWidget(
        state: widget.footerState ?? LoadState.idle,
        isMessage: true,
      );
    }

    // 新消息显示
    if (widget.data != null && widget.data!.isNotEmpty) {
      child = SliverList(
        delegate: SliverChildBuilderDelegate(
          childCount: widget.data?.length ?? 0,
          (context, index) {
            return widget.renderItem?.call(context, index, widget.data?[index]);
          },
        ),
      );
    }

    // 消息为空时显示
    if ((widget.data == null || widget.data!.isEmpty) &&
        (widget.historyData == null || widget.historyData!.isEmpty)) {
      child = SliverToBoxAdapter(
        child: widget.empty ?? Container(),
      );
      footer = Container();
    }

    return CustomScrollView(
      reverse: widget.reverse,
      physics: widget.isAllowScroll == false
          ? const NeverScrollableScrollPhysics()
          : widget.physics,
      controller: _scrollController,
      cacheExtent: 1000,
      shrinkWrap: shrinkWrap,
      slivers: [
        ...?widget.sliverHeader,
        SliverToBoxAdapter(
          child: widget.header,
        ),
        SliverPadding(
          padding: EdgeInsets.only(
            top: widget.padding?.top ?? 0,
          ),
        ),
        child,
        historyChild,
        SliverPadding(
          padding: EdgeInsets.only(
            top: widget.padding?.bottom ?? 0,
          ),
        ),
        SliverToBoxAdapter(
          key: footerKey,
          child: widget.footer,
        ),
        SliverToBoxAdapter(
          child: footer,
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return _buildScrollView();
  }
}
